/*
 * @Author: your name
 * @Date: 2020-08-26 14:12:08
 * @LastEditTime: 2020-08-26 15:02:53
 * @LastEditors: Please set LastEditors
 * @Description: 装饰器
 * @FilePath: /decorator/index.ts
 */
// 类的装饰器
// 装饰器本身是一个函数
// 类装饰器接受的参数是构造函数
// 装饰器通过 @ 符号来使用
function testDecorator() {
  return function<T extends new (...args: any[]) => any>(constructor: T) {
    return class extends constructor {
      name = 'lee';
      getName() {
        return this.name;
      }
    };
  };
}

const Test = testDecorator()(
  class {
    name: string;
    constructor(name: string) {
      this.name = name;
    }
  }
);

const test = new Test('dell');
console.log(test.getName());

// 方法装饰器
// 普通方法，target 对应的是类的 prototype
// 静态方法，target 对应的是类的构造函数
function getNameDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
  // console.log(target, key);
  // descriptor.writable = true;
  descriptor.value = function() {
    return 'decorator';
  };
}

class Test1 {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  @getNameDecorator
  getName() {
    return this.name;
  }
}

const test1 = new Test1('dell');
console.log(test1.getName());

// 访问器装饰器
function visitDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
  // descriptor.writable = false;
}
class VisitTest {
  private _name: string;
  constructor(name: string) {
    this._name = name;
  }
  get name() {
    return this._name;
  }
  @visitDecorator
  set name(name: string) {
    this._name = name;
  }
}

const visitTest = new VisitTest('xiao');
visitTest.name = 'shawn xiao';
console.log(visitTest.name);
